package com.liangbing.utils;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qgf.bean.IdCard;

/**
 * 将加密身份证破解为明文 显示地区等信息
 * http://api.k780.com:88/?app=idcard.get&idcard=110101199001011114&appkey=10003
 * &sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json
 * 
 * @author liangbing
 *
 */
public class IdCardUtils {

	private static int[] weight = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 };
	private static int[] ValideCode = { 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 };
	private static String link = "http://api.k780.com:88/?app=idcard.get&idcard={card}&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json";

	public static void main(String[] args) {

		String initNum = "";
		if (args.length == 0) {
			initNum = "151102*99909**5557";
		} else {
			for (String string : args) {
				System.out.println(string);
			}
			return;
		}
		try {
			init(initNum);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void init(String initNum) throws IOException {
		int count = 0;
		for (int i = 0; i < initNum.length(); i++) {
			if (initNum.charAt(i) == '*') {
				count++;
			}
		}
		// System.out.println(count + "次");
		String max = "";
		for (int i = 0; i < count; i++) {
			max += "9";
		}
		for (int i = 0; i < Integer.valueOf(max); i++) {
			String currNum = intToStr(i, count, initNum);
			String result = checkIdCard(currNum);
			if (result != null) {
				System.out.println(result);
				String info = "";
				try {
					info = getJsonForUrl(link.replace("{card}", result));
				} catch (Exception e) {
					info = "";
					System.err.println("网络请求错误");
				}
				if(!"".equals(info)){
					//String text = JSON.toJSONString(obj);
					//System.out.println(info);
					JSONObject json = (JSONObject)JSON.parse(info);
					IdCard idCard = JSON.parseObject(json.getString("result"), IdCard.class);
					System.out.println("=================================");
					System.out.println(idCard);
				}
			}
		}

	}

	
	/**
	 * 将身份证中*号填充
	 */
	private static String intToStr(int i, int count, String idNum) {
		String result = i + "";
		int needLen = count - result.length();
		for (int j = 0; j < needLen; j++) {
			result = "0" + result;
		}
		for (int j = 0; j < count; j++) {
			idNum = idNum.replaceFirst("\\*", result.charAt(j) + "");
		}
		return idNum;
	}

	/**
	 * ，将前17位的数字与其对应的加权因子相乘，再将积相加，最后的和再除以11，取其余。除以11最后的余有11种可能，从0到10。通过余再做一个转换，
	 * 即可得到相应的第18位上的校验码，余数和校验码的转换如下：
	 */
	public static String checkIdCard(String idNum) {

		int sum = 0;
		String varStr = idNum.substring(idNum.length() - 1);
		for (int i = 0; i < idNum.length() - 1; i++) {
			int intNum = Character.getNumericValue(idNum.charAt(i));
			sum += intNum * weight[i];
		}
		int ram = sum % 11;
		// System.out.println(ram);
		// System.out.println("尾数是：" + ValideCode[ram]);
		String calaStr = ValideCode[ram] == 10 ? "x" : ValideCode[ram] + "";
		// System.out.println(varStr.equals(calaStr));
		if (varStr.equals(calaStr)) {
			if (getYearByIdCard(idNum) < 2300 && getYearByIdCard(idNum) > 1900 
					&& getMouthByIdCard(idNum) > 0 && getMouthByIdCard(idNum) <= 12
					&& getDayByIdCard(idNum) > 0 && getDayByIdCard(idNum) <= 31) {
				return idNum;
			}
		}
		return null;
	}

	
	public static String getJsonForUrl(String link) throws IOException {
		URL url = new URL(link);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setConnectTimeout(100);
		conn.connect();
		InputStream in = conn.getInputStream();
		byte[] bytes = new byte[1024];
		int len = 0;
		String reuslt = "";
		while ((len = in.read(bytes)) != -1) {
			String str = new String(bytes,0,len,"utf-8");
			reuslt += str;
		}
		in.close();
		return reuslt;
	}
	
	public static int getYearByIdCard(String idNum) {
		if (idNum.length() != 18) {
			return 0;
		}
		return new Integer(idNum.substring(6, 10));
	}

	public static int getMouthByIdCard(String idNum) {
		if (idNum.length() != 18) {
			return 0;
		}
		return new Integer(idNum.substring(10, 12));
	}

	public static int getDayByIdCard(String idNum) {
		if (idNum.length() != 18) {
			return 0;
		}
		return new Integer(idNum.substring(12, 14));
	}
}
